package comp
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	
	import mx.controls.ToolTip;
	import mx.core.UIComponent;
	import mx.effects.EffectInstance;
	import mx.effects.IEffect;
	import mx.events.EffectEvent;
	
	public class EffectToolTip extends ToolTip
	{
		public static var hideEffect:IEffect;
		
		private static var allEffects:Array = [];
		
		private var _skipEventsHandling:Boolean = false;
		
		public function EffectToolTip()
		{
			super();
			
			this.addEventListener(Event.REMOVED, meRemoved);
			
			// when we show this tool tip, end effect playing for others so no 2 tool tips stay on screen at the same time
			callLater(endOthersEffects);
		}
		
		private function meRemoved(event:Event):void {
			if (_skipEventsHandling) {
				return;
			}
			
			var target:DisplayObject = event.target as DisplayObject;
			if (target && target is UIComponent) {
				var parent:DisplayObjectContainer = target.parent as DisplayObjectContainer;
				if (parent) {
					var ndx:int = parent.getChildIndex(target);
					if (ndx >= 0) {
						// allow manager time to remove this tool tip from parent
						(target as UIComponent).callLater(playHideEffect, [target, parent]);
					}
				}
			}
		}
		
		private function playHideEffect(target:DisplayObject, parent:DisplayObjectContainer) : void{
			// if this tool tip instance is re-displayed (for example, for list items), skip hide effect
			if (!hideEffect || target.parent) {
				return;
			}
			
			// at this point, manager removed tool tip from parent, so now we re-add it and play effect
			// without this sequence of events/actions, hide effect is not playing because this
			// instance is not in the parent
			
			_skipEventsHandling = true;
			
			// a bit of hack to force tool tip to be added back into container so it is visible for duration of
			// hide effect playing
			parent.parent.addChild(target);
			
			// Play hide effect.
			var instances: Array = hideEffect.play([target]);
			for (var i:int = 0; i<instances.length; i++) {
				(instances[i] as EffectInstance).addEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
			}
			allEffects = allEffects.concat(instances);
			
			_skipEventsHandling = false;
		}
		
		private function handleEffectEnd(event:EffectEvent):void {
			_skipEventsHandling = true;
			
			(event.effectInstance as EffectInstance).removeEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
			(event.effectInstance as EffectInstance).end();
			
			// remove myself from parent after re-adding in playFadeEffect method
			parent.removeChild(this);
			
			_skipEventsHandling = false;
		}
		
		private function endOthersEffects():void {
			for (var i:int = 0; i<allEffects.length; i++) {
				(allEffects[i] as EffectInstance).end();
			}
			allEffects = [];
		}
		
	}
	
}